#include "flash_on_chip.h"
#include "spi.h"
/**
 * @brief  擦除指定地址范围内的 Flash
 * @param  addr 起始地址（必须是页对齐，即 1KB 的倍数）
 * @param  len  要擦除的字节长度
 * @retval 0 成功
 *        -1 参数错误（越界）
 *        -2 地址未对齐
 *        -3 擦除失败
 */
int flash_erase(uint32_t addr, uint32_t len)
{
    if (len == 0) return -1;
    if (addr < BOOT_START_ADDR || (addr + len) > OTA_END_ADDR)
	{
		printf("%08x %08x \r\n",(addr + len),OTA_END_ADDR);
		return -1;}
    if (addr % FLASH_PAGE_SIZE != 0) return -2;   // 必须页对齐

    uint32_t end = addr + len;
    HAL_FLASH_Unlock();

    FLASH_EraseInitTypeDef er = {0};
    uint32_t err = 0;

    uint32_t first_page = (addr - BOOT_START_ADDR) / FLASH_PAGE_SIZE;
    uint32_t last_page  = (end  - BOOT_START_ADDR + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;

    for (uint32_t p = first_page; p < last_page; ++p)
    {
        er.TypeErase   = FLASH_TYPEERASE_PAGES;
        er.PageAddress = BOOT_START_ADDR + p * FLASH_PAGE_SIZE;
        er.NbPages     = 1;
        if (HAL_FLASHEx_Erase(&er, &err) != HAL_OK)
        {
            HAL_FLASH_Lock();
            return -3;
        }
    }

    HAL_FLASH_Lock();
    return 0;
}

/**
 * @brief  向 Flash 写入数据（半字编程）
 * @param  addr 写入起始地址（必须是 2 字节对齐）
 * @param  data 待写入数据缓冲区
 * @param  len  数据长度（字节数）
 * @retval 0 成功
 *        -1 参数错误（越界）
 *        -2 地址未对齐
 *        -3 写入失败
 */
int flash_write(uint32_t addr, const uint8_t *data, uint32_t len)
{
    if (len == 0) return 0;
    if (addr < BOOT_START_ADDR || (addr + len) > OTA_END_ADDR) return -1;
    if (addr % 2 != 0) return -2;   // 必须半字对齐

    HAL_FLASH_Unlock();

    for (uint32_t i = 0; i < len; i += 2)
    {
        uint16_t half = data[i] | ((i + 1 < len ? data[i + 1] : 0xFF) << 8);

        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr + i, half) != HAL_OK)
        {
            HAL_FLASH_Lock();
            return -3;
        }
    }

    HAL_FLASH_Lock();
    return 0;
}

/**
 * @brief  从 Flash 指定地址读取数据
 * @param  addr 起始地址
 * @param  buf  目标缓冲区
 * @param  len  要读取的字节数
 * @retval 0 成功
 *        -1 参数错误（越界）
 */
int flash_read(uint32_t addr, uint8_t *buf, uint32_t len)
{
    if (len == 0) return 0;
    if (addr < BOOT_START_ADDR || (addr + len) > OTA_END_ADDR) return -1;

    const uint8_t *src = (const uint8_t *)addr;
    for (uint32_t i = 0; i < len; i++)
    {
		if(i % 16 == 0) printf("\r\n");
//		printf("%02X",src[i]);
		
		
    }
	printf("\r\n");
    return 0;
}
